package com.emperor.work.app;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;

import com.emperor.cashier.app.CashierAppCtrl;
import com.emperor.core.app.App;
import com.emperor.core.app.AppBase;
import com.emperor.core.app.AppConstant;
import com.emperor.inventory.app.InventoryAppCtrl;
import com.emperor.user.logic.User;
import com.emperor.user.logic.UserModel;
import com.emperor.util.DateFormatter;
import com.emperor.util.HibernateUtil;
import com.emperor.work.logic.Work;
import com.emperor.work.logic.WorkModel;
import com.swtdesigner.SWTResourceManager;

public class WorkAppNew extends AppBase implements App {

	private Combo usernameCombo;
	private Combo combo;
	private Text text_2;
	protected Shell shell;

	public static Logger log = Logger.getLogger(WorkAppNew.class);

	public WorkAppNew() {
		super();
	}

	public WorkAppNew(Map<String, Object> params) {
		super();
		this.params = params;
	}

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			WorkAppNew window = new WorkAppNew();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window
	 */
	public void open() {
		final Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}

	/**
	 * Create contents of the window
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setBackgroundImage(SWTResourceManager.getImage(WorkAppNew.class, "/img/main.jpg"));
		shell.setImage(SWTResourceManager.getImage(WorkAppNew.class, "/img/iMac OSX.png"));
		shell.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
		shell.setText("New Work Sheet");
		shell.setSize(1280, 800);

		initScreen(shell, getParams());

		final Composite composite = new Composite(shell, SWT.NONE);
		composite.setBounds(0, 50, 1262, 317);

		final Label messageLabel = new Label(composite, SWT.NONE);
		messageLabel.setBounds(10, 10, 972, 20);
		messageLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		messageLabel
				.setText("Please key in your username and password and choose the work type you want to record.");

		final Label usernameLabel = new Label(composite, SWT.NONE);
		usernameLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		usernameLabel.setText("Username");
		usernameLabel.setBounds(10, 86, 75, 20);

		final Label usernameLabel_1 = new Label(composite, SWT.NONE);
		usernameLabel_1.setBounds(10, 122, 75, 20);
		usernameLabel_1.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		usernameLabel_1.setText("Password");

		text_2 = new Text(composite, SWT.BORDER | SWT.PASSWORD);
		text_2.setBounds(113, 119, 447, 30);
		text_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));

		combo = new Combo(composite, SWT.READ_ONLY);
		combo.setVisibleItemCount(6);
		combo.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		combo.setBounds(113, 153, 447, 28);
		
		combo.add(Work.TYPE_WORK_IN);
		combo.add(Work.TYPE_WORK_OUT);
		combo.add(Work.TYPE_LUNCH_IN);
		combo.add(Work.TYPE_LUNCH_OUT);
		combo.add(Work.TYPE_2ND_BREAK_IN);
		combo.add(Work.TYPE_2ND_BREAK_OUT);
		
		combo.select(0);

		final Button submitButton = new Button(composite, SWT.NONE);
		submitButton.setImage(SWTResourceManager.getImage(WorkAppNew.class, "/img/Save.png"));
		submitButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				try {
					if (usernameCombo.getText().length() > 0
							&& text_2.getText().length() > 0 && combo.getText().length() > 0) {

						Session session = HibernateUtil.getSessionFactory()
								.getCurrentSession();
						try {
							session.beginTransaction();
							User user = (User) session.createCriteria(
									UserModel.class).add(
									Expression.eq(User.FLD_USERNAME, usernameCombo
											.getText())).add(
									Expression.eq(User.FLD_PASSWORD, text_2
											.getText())).uniqueResult();

							if (user != null && user.getId() != null
									&& user.getEmployee() != null) {
								Work work = new WorkModel();
								
								work.setEmployee(user.getEmployee());
								work.setType(combo.getText());
								
								work = (Work)preAdd(work, getParams());
								work.setStatus(AppConstant.STATUS_ACTIVE);
								work.setPunch(new Date());
								
								session.save(work);
								if (work.getId() != null) {
									message(getShell(), "Save Success.", "Worksheet added successfully for " + work.getEmployee().getName() + ".");
									getShell().close();
								} else {
									message(getShell(), "Save Error.", "Unable to add worksheet.", SWT.ICON_ERROR | SWT.OK);
								}
							} else {
								message(getShell(), "Save Error.", "Invalid username and password.", SWT.ICON_ERROR | SWT.OK);
							}
							session.getTransaction().commit();
						} catch (Exception ex) {
							session.getTransaction().rollback();
							log.error("Unable to add new worksheet.", ex);
						}

					} else {
						message(getShell(), "Save Error.", "Please key in username, password and select work type.");
					}
				} catch (Exception ex) {
					log.error("Unable to add worksheet", ex);
				}
			}
		});
		submitButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		submitButton.setText("Save");
		submitButton.setBounds(113, 187, 75, 30);

		final Label usernameLabel_2 = new Label(composite, SWT.NONE);
		usernameLabel_2.setBounds(10, 156, 75, 20);
		usernameLabel_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		usernameLabel_2.setText("Type");
		
		final Label timerLabel = new Label(composite, SWT.NONE);
		timerLabel.setForeground(SWTResourceManager.getColor(0, 0, 128));
		timerLabel.setFont(SWTResourceManager.getFont("", 18, SWT.BOLD));
		timerLabel.setText("12:00:00 PM");
		timerLabel.setBounds(113, 47, 140, 30);

		final Button submitButton_1 = new Button(composite, SWT.NONE);
		submitButton_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				getShell().close();
			}
		});
		submitButton_1.setImage(SWTResourceManager.getImage(WorkAppNew.class, "/img/Refresh.png"));
		submitButton_1.setBounds(194, 187, 80, 30);
		submitButton_1.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		submitButton_1.setText("Reset");

		usernameCombo = new Combo(composite, SWT.NONE);
		usernameCombo.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI", 12, SWT.NORMAL));
		usernameCombo.setBounds(113, 85, 447, 28);
		
		final SimpleDateFormat sdf = new SimpleDateFormat(DateFormatter.HHMMSS);
		final Runnable timer = new Runnable() {
			public void run() {
				timerLabel.setText(sdf.format(new Date()));
				getShell().getDisplay().timerExec(1000, this);
			}
		};
		getShell().getDisplay().timerExec(1000, timer);
		getShell().addShellListener(new ShellAdapter() {
			public void shellClosed(final ShellEvent e) {
				getShell().getDisplay().timerExec(-1, timer);
			}
		});
		
		//
		buildStandardMenu(getShell(), getParams(), CashierAppCtrl.CASHIER_CTRL, CashierAppCtrl.CASHIER_FORM);
		populateUsername(usernameCombo);
	}

	private List<String> validateForm(Work work) {
		List<String> errors = new ArrayList<String>();
		
		if (work.getEmployee() == null) {
			errors.add("Invalid employee username and password.");
		}
		if (work.getPunch() == null) {
			errors.add("Invalid punch time.");
		}
		if (StringUtils.isEmpty(work.getType())) {
			errors.add("Type cannot be empty.");
		}
		
		return errors;
	}
	
	private void populateUsername(Combo combo) {
		try {
			Session session = HibernateUtil.getSessionFactory().getCurrentSession();
			session.beginTransaction();
			
			List<User> users = session.createCriteria(UserModel.class).add(Expression.eq(User.FLD_STATUS, AppConstant.STATUS_ACTIVE)).addOrder(Order.asc(User.FLD_USERNAME)).list();
			if (users != null && !users.isEmpty()) {
				for (Iterator<User> iter = users.iterator(); iter.hasNext(); ) {
					User user = iter.next();
					combo.add(user.getUsername());
				}
			}
		} catch(Exception e) {
			log.error("Unable to populate username.", e);
		}
	}
	
	public Shell getShell() {
		return shell;
	}

}
